<template>
  <div class="aetherupload-container">
    <div class="upload-text">
      <el-button type="primary" @click="handleClick" @change="handleChange">上传
        <i class="el-icon-upload el-icon--right"></i>
        <input type="file" v-show="false" @change="handleChange" ref="fileinput">
      </el-button>
      <div class="upload-dec">
        <div class="progress-group" v-show="loading">
          <p>
            <span>{{fileName}}</span> 正在上传</p>
          <el-progress :percentage="progress"></el-progress>
        </div>
        <a class="upload-file-name" v-show="!loading && getFileUrl">
          <i class="el-icon-document"></i>{{getFileUrl}}
        </a>
      </div>
    </div>
    <div slot="tip" class="el-upload__tip">{{tip}}</div>
  </div>
</template>

<script>
import fetch from 'utils/fetch'

export default {
  name: 'aetherupload',
  data() {
    return {
      fileUpload: {},
      uploadSet: {
        group: 'file',
        uploadBaseName: '',
        uploadExt: '',
        chunkSize: 0,
        chunkCount: 0,
        subDir: '',
        savedPath: ''
      },
      fileName: '',
      chunkIndex: 0,
      progress: 0,
      loading: false,
      fileFormData: new FormData()
    }
  },
  props: {
    value: String,
    tip: String
  },
  methods: {
    rmImage() {
      this.emitInput('')
    },
    emitInput(val) {
      this.$emit('input', val)
    },
    reset() {
      this.fileName = ''
      this.chunkIndex = 0
      this.progress = 0
      this.savedPath = ''
    },
    handleImageScucess() {
      this.emitInput('')
    },
    handleRemove(file, fileList) {
      console.log(file, fileList)
    },
    handlePreview(file) {
      console.log(file)
    },
    handleChange(e) {
      e.preventDefault()

      const blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice
      if (!blobSlice) {
        this.$message({
          showClose: true,
          message: '上传组件不被此浏览器支持',
          type: 'warning'
        })
        return false
      }
      this.reset()

      const files = e.target.files || e.dataTransfer.files

      if (files.length < 0) {
        return false
      } else {
        this.fileUpload = files[0]

        this.preprocess()
      }
    },
    handleClick(e) {
      if (this.loading !== 1) {
        if (e.target !== this.$refs.fileinput) {
          e.preventDefault()
          if (document.activeElement !== this.$refs) {
            this.$refs.fileinput.click()
          }
        }
      }
    },
    preprocess() { // 预处理
      this.loading = true
      this.fileName = this.fileUpload.name

      fetch({
        url: 'aetherupload/preprocess',
        method: 'post',
        data: {
          file_name: this.fileUpload.name,
          file_size: this.fileUpload.size,
          file_hash: this.fileUpload.fileHash,
          group: this.uploadSet.group
        }
      }).then(res => {
        const resData = res.data
        if (resData.error !== 0) {
          this.$message({
            showClose: true,
            message: resData.error,
            type: 'error'
          })

          this.loading = false
          return
        }

        this.uploadSet.uploadBaseName = resData.uploadBaseName
        this.uploadSet.uploadExt = resData.uploadExt
        this.uploadSet.chunkSize = resData.chunkSize
        this.uploadSet.chunkCount = Math.ceil(this.fileUpload.size / this.uploadSet.chunkSize)
        this.uploadSet.subDir = resData.subDir

        if (resData.savedPath.length === 0) {
          this.uploadChunk()
        } else {
          // 未实现
          console.log(resData.savedPath)
          console.log('秒传成功')
        }
      }).catch(error => {
        this.$message({
          showClose: true,
          message: error.message,
          type: 'error'
        })
      })
    },
    uploadChunk() { // 块上传
      const start = this.chunkIndex * this.uploadSet.chunkSize
      const end = Math.min(this.fileUpload.size, start + this.uploadSet.chunkSize)
      // var form = new FormData()
      console.log(start + '' + end)
      this.fileFormData.set('file', this.fileUpload.slice(start, end))
      this.fileFormData.set('upload_ext', this.uploadSet.uploadExt)
      this.fileFormData.set('chunk_total', this.uploadSet.chunkCount)
      this.fileFormData.set('chunk_index', this.chunkIndex + 1)
      this.fileFormData.set('upload_basename', this.uploadSet.uploadBaseName)
      this.fileFormData.set('group', this.uploadSet.group)
      this.fileFormData.set('sub_dir', this.uploadSet.subDir)

      const headers = { 'content-type': 'multipart/form-data' }
      fetch({
        url: 'aetherupload/uploading',
        method: 'post',
        data: this.fileFormData,
        headers: headers
      }).then(res => {
        const resData = res.data

        if (resData.error !== 0) {
          this.$message({
            showClose: true,
            message: resData.error,
            type: 'error'
          })
          this.loading = false
          return false
        }

        const percent = parseInt((this.chunkIndex + 1) / this.uploadSet.chunkCount * 100)

        this.progress = percent

        if (this.chunkIndex + 1 === this.uploadSet.chunkCount) {
          this.chunkIndex = 0 // 重置块索引
          this.uploadSet.savedPath = resData.savedPath

          this.loading = false

          this.emitInput(resData.savedPath)

          return false
        }

        ++this.chunkIndex
        this.uploadChunk()
      }).catch(res => {
        this.loading = false
        console.log(res)
      })
    },
    continueUpload() {
      this.$confirm('数据块输出出现错误, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.uploadChunk()
      }).catch(() => {
        this.loading = false
      })
    }
  },
  computed: {
    getFileUrl() {
      return this.value
    }
  }
}
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
.aetherupload-container {
  .upload-text {
    overflow: hidden;
  }
  .el-button {
    float: left;
  }
  .upload-dec {
    padding-left: 100px;
    height: 36px; // padding: 8px 0;
  }
  .upload-file-name {
    color: #48576a;
    margin-left: 10px;
    overflow: hidden;
    text-overflow: ellipsis;
    transition: color .3s;
    white-space: nowrap;
    font-size: 16px;
  }
  .progress-group {
    p {
      color: #48576a;
      margin-top: 0;
      margin-bottom: 4px;
      line-height: 1;
    }
  }
}
</style>